package taskflow.constants;

import org.apache.commons.lang3.StringUtils;

import java.util.function.Function;

/**
 * @author ALi
 * @version 1.0
 * @date 2023-04-20 16:28
 * @description
 */
public class Parameter<T> {
    public static final Parameter<Boolean> WORK_NO_EXISTS_IGNORABLE = new Parameter<>("taskflow.ignoreNoExists", false, Boolean::getBoolean);
    public static final Parameter<Integer> WORK_MAX_TASKS = new Parameter<>("taskflow.work.maxTasks", 1000, Integer::getInteger);
    public static final Parameter<Boolean> WORK_TRACEABLE = new Parameter<>("taskflow.work.traceable", false, Boolean::getBoolean);
    public static final Parameter<Long> TASK_ASYNC_TIMEOUT = new Parameter<>("taskflow.task.asyncTimeOut", 30000L, Long::getLong);
    public static final Parameter<Boolean> RELOAD_ENABLE = new Parameter<>("taskflow.reload.enable", true, Boolean::getBoolean);
    public static final Parameter<Boolean> LOG_PRINTABLE = new Parameter<>("taskflow.log.printable", true, Boolean::getBoolean);
    public static final Parameter<Boolean> LOG_PRINT_DETAIL = new Parameter<>("taskflow.log.printDetail", false, Boolean::getBoolean);

    private String name;
    private T defaultValue;
    private Function<String,T> valueGetter;
    private Parameter(String name, T defaultValue, Function<String, T> valueGetter){
        this.name = name;
        this.defaultValue = defaultValue;
        this.valueGetter = valueGetter;
    }

    public void setValue(String value) {
        if (value != null) {
            System.setProperty(name, value);
        }
    }

    public void refresh(Function<String, String> source) {
        String value = source.apply(name);
        if(!StringUtils.isEmpty(value)){
            setValue(value);
        }
    }
    public T getValue() {
        T value = valueGetter.apply(name);
        return value == null ? defaultValue : value;
    }

    public static boolean isLegal(String name){
        if (name == null || name.length() == 0) {
            return false;
        }
        return name.equals(WORK_NO_EXISTS_IGNORABLE.name)
                || name.equals(WORK_MAX_TASKS.name)
                || name.equals(WORK_TRACEABLE.name)
                || name.equals(TASK_ASYNC_TIMEOUT.name)
                || name.equals(RELOAD_ENABLE.name)
                || name.equals(LOG_PRINTABLE.name)
                || name.equals(LOG_PRINT_DETAIL.name);
    }
}
